package cloud.maque.gateway.config;


import cloud.maque.common.core.response.R;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import jakarta.annotation.PostConstruct;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * 网关限流配置
 */
@Configuration
public class GatewayConfiguration {

    @PostConstruct
    public void initBlockHandlers() {
        BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {
            @Override
            public Mono<ServerResponse> handleRequest(ServerWebExchange exchange, Throwable t) {

                String exceptionClassName = t.getClass().getName();
                R<String> r = new R<String>();
                r.setCode(HttpStatus.TOO_MANY_REQUESTS.value());
                if (exceptionClassName.equals("com.alibaba.csp.sentinel.slots.block.degrade.DegradeException")) {
                    r.setMsg("服务降级！");
                } else if (exceptionClassName.equals("com.alibaba.csp.sentinel.slots.block.flow.FlowException")) {
                    r.setMsg("服务流量过大!");
                } else if (exceptionClassName.equals("com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException")){
                    r.setMsg("服务流量过大!");
                } else {
                    r.setMsg(exceptionClassName);
                }

                return ServerResponse.status(HttpStatus.TOO_MANY_REQUESTS)
                        .contentType(MediaType.APPLICATION_JSON)
                        .body(BodyInserters.fromValue(r));
            }
        };
        //设置自定义异常处理器
        GatewayCallbackManager.setBlockHandler(blockRequestHandler);
    }
}